home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / programming / source / fbm12s.lha / fbext.c < prev    next >
C/C++ Source or Header  |  1994-07-18  |  7KB  |  224 lines

  1. /*****************************************************************
  2.  * fbext.c: FBM Release 1.2 07-Apr-93 Michael Mauldin
  3.  *
  4.  * Copyright (C) 1989-1993 by Michael Mauldin.  Permission is granted
  5.  * to use this file in whole or in part for any purpose, educational,
  6.  * recreational or commercial, provided that this copyright notice
  7.  * is retained unchanged.  This software is available to all free of
  8.  * charge by anonymous FTP and in the UUNET archives.
  9.  *
  10.  * fbext.c: 
  11.  *
  12.  * USAGE
  13.  *    % fbext [ -w<width> -h<height> -W<maxwidth> -H<maxheight>
  14.  *         -a<aspect> -t'title' -c'credits' ]
  15.  *           [ x y width height ] < foo.fbm > bar.fbm
  16.  *
  17.  * EDITLOG
  18.  *    LastEditDate = Mon Jun 25 00:02:18 1990 - Michael Mauldin
  19.  *    LastFileName = /usr2/mlm/src/misc/fbm/fbext.c
  20.  *
  21.  * HISTORY
  22.  * 07-Apr-93  Michael Mauldin (mlm) at Carnegie-Mellon University
  23.  *    Added -J switch
  24.  *
  25.  * 25-Jun-90  Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
  26.  *    Package for Release 1.0
  27.  *
  28.  * 20-May-89  Michael Mauldin (mlm) at Carnegie Mellon University
  29.  *    Bug fix from Dave Cohrs <dave@cs.wisc.edu>
  30.  *
  31.  * 20-Apr-89  Michael Mauldin (mlm) at Carnegie Mellon University
  32.  *    Beta release (version 0.91) mlm@cs.cmu.edu
  33.  *
  34.  * 22-Aug-88  Michael Mauldin (mlm) at Carnegie-Mellon University
  35.  *    Created.
  36.  *****************************************************************/
  37.  
  38. # include <stdio.h>
  39. # include <math.h>
  40. # include "fbm.h"
  41.  
  42. int allowrot = 0;
  43.  
  44. # define USAGE \
  45. "Usage:    fbext [ -w<width> -h<height> ] [ -R ]\n\
  46.           [ -W<maxwdith> -H<maxheight> -s<size> ]\n\
  47.           [ -a<aspect> -t'title' -c'credits' ] [ -<type> ]\n\
  48.           [ x y [ width height ] ]    < image > image"
  49.  
  50. #ifndef lint
  51. static char *fbmid =
  52. "$FBM fbext.c <1.2> 07-Apr-93 (C) 1989-1993 by Michael Mauldin, source \
  53. code available free from MLM@CS.CMU.EDU and from UUNET archives$";
  54. #endif
  55.  
  56. main (argc, argv)
  57. char *argv[];
  58. { int xo = -1, yo = -1, w = -1, h = -1, ow = -1, oh = -1, size = -1;
  59.   int mh = -1, mw = -1;
  60.   double aspect = -1.0;
  61.   char title[FBM_MAX_TITLE], credits[FBM_MAX_TITLE];
  62.   FBM input, rotated, output, *image = &input;
  63.   int outtype = FMT_FBM;
  64.  
  65.   /* Clear the memory pointers so alloc_fbm won't be confused */
  66.   input.cm  = input.bm  = (unsigned char *) NULL;
  67.   rotated.cm = rotated.bm = (unsigned char *) NULL;
  68.   output.cm = output.bm = (unsigned char *) NULL;
  69.  
  70.   title[0] = '\0';
  71.   credits[0] = '\0';
  72.  
  73.   /* Get the options */
  74.   while (--argc > 0 && (*++argv)[0] == '-')
  75.   { while (*++(*argv))
  76.     { switch (**argv)
  77.       { case 't':    strcpy (title, *argv+1); CLRARG; break;
  78.     case 'c':    strcpy (credits, *argv+1); CLRARG; break;
  79.     case 'a':    aspect = atof (*argv+1); SKIPARG; break;
  80.     case 'w':    ow = atoi (*argv+1); SKIPARG; break;
  81.     case 'h':    oh = atoi (*argv+1); SKIPARG; break;
  82.     case 'W':    mw = atoi (*argv+1); SKIPARG; break;
  83.     case 'H':    mh = atoi (*argv+1); SKIPARG; break;
  84.     case 'r':    allowrot++; break;
  85.     case 's':    size = atoi (*argv+1); SKIPARG; break;
  86.     case 'A':    outtype = FMT_ATK; break;
  87.     case 'B':    outtype = FMT_FACE; break;
  88.     case 'F':    outtype = FMT_FBM; break;
  89.     case 'G':    outtype = FMT_GIF; break;
  90.     case 'I':    outtype = FMT_IFF; break;
  91.     case 'J':    outtype = FMT_JPEG; break;
  92.     case 'L':    outtype = FMT_LEAF; break;
  93.     case 'M':    outtype = FMT_MCP; break;
  94.     case 'P':    outtype = FMT_PBM; break;
  95.     case 'R':    outtype = FMT_RLE; break;
  96.     case 'S':    outtype = FMT_SUN; break;
  97.     case 'T':    outtype = FMT_TIFF; break;
  98.     case 'X':    outtype = FMT_X11; break;
  99.     case 'Z':    outtype = FMT_PCX; break;
  100.     default:    fprintf (stderr, "%s\n", USAGE);
  101.             exit (1);
  102.       }
  103.     }
  104.   }
  105.  
  106.  
  107.   if (read_bitmap (&input, (char *) NULL))
  108.   {
  109.     if (image->hdr.physbits != 8)
  110.     { fprintf (stderr,
  111.            "Can't handle images with %d bits and %d physbits per pixel\n",
  112.            image->hdr.bits, image->hdr.physbits);
  113.       exit (1);
  114.     }
  115.  
  116.     /* Get arguments */
  117.     if (argc > 0)    xo    = atoi (argv[0]);
  118.     if (xo < 0)        xo    = 0;
  119.  
  120.     if (argc > 1)    yo    = atoi (argv[1]);
  121.     if (yo < 0)        yo    = 0;
  122.  
  123.     if (argc > 2)    w    = atoi (argv[2]);
  124.     if (w < 0)        w    = image->hdr.cols - xo;
  125.  
  126.     if (argc > 3)    h    = atoi (argv[3]);
  127.     if (h < 0)        h    = image->hdr.rows - yo;
  128.  
  129.     if (argc > 4)    ow    = atoi (argv[4]);
  130.  
  131.     if (argc > 5)    aspect = atof (argv[5]);
  132.     
  133.     /* If 'allowrot' is on, rotate image if its fits better */
  134.     if (allowrot && mh > 0 && mw > 0)
  135.     { int inhoriz=0, outhoriz=0;
  136.     
  137.       if (aspect < 0.0) aspect = 1.0;
  138.     
  139.       if (image->hdr.cols >= (image->hdr.aspect * image->hdr.rows)) inhoriz++;
  140.       if (mw >= (aspect * mh))                     outhoriz++;
  141.       
  142.       if (inhoriz != outhoriz)
  143.       { if (rotate_fbm (image, &rotated, 90))
  144.         { free (image);
  145.       image = &rotated;
  146.       
  147.       fprintf (stderr, "Rotating [%dx%d] image for better fit [%dx%d]\n",
  148.            image->hdr.rows, image->hdr.cols, mw, mh);
  149.     }
  150.       }
  151.       else
  152.       { exit (1); }
  153.     }
  154.  
  155.     /* If max number of pixels specified, calculate width and height */
  156.     if (size > 0)
  157.     { if (ow > 0 || oh > 0)
  158.       { fprintf (stderr,
  159.       "fbext: error, can only specify one of size and width,height\n");
  160.     exit (1);
  161.       }
  162.       
  163.       aspect = 1.0;
  164.  
  165.       ow = sqrt ((double) size * w / (h * image->hdr.aspect));
  166.       ow &= ~7;            /* Make width multiple of 8 */
  167.       oh = ow * image->hdr.aspect * h / w;
  168.     }
  169.  
  170.     /* If given width and height, must determine output aspect */
  171.     if (aspect <= 0.0)
  172.     { if (ow > 0 && oh > 0)
  173.       { aspect = image->hdr.aspect * ow * h / (oh * w); }
  174.       else
  175.       { aspect = image->hdr.aspect; }
  176.     }
  177.  
  178.     /* If given only maximum sizes, assume largest width */
  179.     if (ow <= 0 && oh <= 0)
  180.     { if (mw > 0)    ow = mw;
  181.       else if (mh > 0)    oh = mh;
  182.     }
  183.  
  184.     /*
  185.      * If given one of width or height, calculate the other.
  186.      * If given only aspect ratio, inflate the smaller dimension
  187.      */
  188.  
  189.     if (ow > 0 && oh > 0)
  190.     { /* Nothing to pick */ }
  191.     else if (ow <= 0 && oh > 0)
  192.     { ow = ((double) oh + 0.5) * (aspect / image->hdr.aspect) * w / h; }
  193.     else if (ow > 0 && oh <= 0)
  194.     { oh = ((double) ow + 0.5) * (image->hdr.aspect / aspect) * h / w; }
  195.     else if (aspect != image->hdr.aspect)
  196.     { if (aspect > image->hdr.aspect)
  197.       { oh = h;
  198.         ow = ((double) oh + 0.5) * (aspect / image->hdr.aspect) * w / h;
  199.       }
  200.       else
  201.       { ow = w;
  202.         oh = ((double) ow + 0.5) * (input.hdr.aspect / aspect) * h / w;
  203.       }
  204.     }
  205.     else
  206.     { ow = w; oh = h; }
  207.      
  208.     /* If either dimension exceeds given maximums, shrink the image to fit */
  209.     if (mh > 0 && oh > mh)
  210.     { ow = ow * mh / oh; oh = mh; }
  211.  
  212.     /* Now extract the specified rectangle and write it out */
  213.     if (mw > 0 && ow > mw)
  214.     { oh = oh * mw / ow; ow = mw; }
  215.  
  216.     if (extract_fbm (&input, &output, xo, yo, w, h, ow, oh,
  217.              title[0] ? title : NULL,
  218.              credits[0] ? credits : NULL))
  219.     { if (write_bitmap (&output, stdout, outtype)) exit (0); }
  220.   }
  221.   
  222.   exit (1);
  223. }
  224.